;(function (name) {
    window.components = window.components || {}
    window.components[name] = {
        name,
        emits: ['update:modelValue', 'menuClick'],
        props: {
            modelValue: {
                type: Boolean,
                default: false
            },
            menus: {
                type: Array,
                default: () => []
            },
            selector: {
                type: String
            }
        },
        data() {
            return {
                position: {
                    x: 0,
                    y: 0
                },
                width: 'initial',
                height: 'initial',
                state: this.modelValue,
                target: {},
                contextValue: '',
                dataset: {},
                triggerNode: null
            }
        },
        computed: {
            style() {
                return {
                    left: this.position.x,
                    top: this.position.y,
                    position: 'fixed',
                    width: this.width + 'px',
                    height: this.height + 'px'
                }
            },
            showMenus() {
                return this.menus.filter(it => !it.when || it.when(this.contextValue))
            }
        },
        mounted() {
            const dom = document.querySelector(this.selector)
            dom.addEventListener('contextmenu', event => {
                event.preventDefault()
                this.show(event)
            })
            document.addEventListener('click', () => {
                this.hide()
            })
            window.addEventListener('blur', () => {
                this.hide()
            })
            this.target = dom
        },
        methods: {
            onClick(menu, index) {
                this.$emit('menuClick', menu, this.dataset)
                this.hide()
            },
            hide() {
                this.height = 'initial'
                this.width = 'initial'
                this.state = false
            },
            show(event) {
                let temp = event.target
                let menuItem
                while (temp && temp != this.target) {
                    const contextValue = temp.dataset.contextValue
                    if (contextValue) {
                        this.contextValue = contextValue
                        this.dataset = temp.dataset
                        menuItem = temp
                        break
                    }
                    temp = temp.parentElement
                }
                if (!menuItem) {
                    this.hide()
                    return
                }
                if (!this.showMenus.length) {
                    this.hide()
                    return
                }
                this.position = {
                    x: event.pageX + 'px',
                    y: event.pageY + 'px'
                }
                this.triggerNode?.classList.toggle('focus')
                this.triggerNode = menuItem
                this.triggerNode.focus()
                this.triggerNode.classList.toggle('focus')
                this.state = true
                this.$nextTick(() => {
                    const menu = document.getElementById('explorer-menu')
                    const bound = menu.getBoundingClientRect()
                    const wh = window.innerHeight
                    const ww = window.innerWidth
                    let xOver = false
                    if (bound.right > ww) {
                        let x = bound.left - (bound.right - ww) - 4
                        if (x < 0) {
                            x = 0
                        }
                        xOver = true
                        this.position.x = x + 'px'
                    }
                    if (bound.bottom > wh) {
                        let y
                        if (xOver) {
                            if (bound.top >= bound.height) {
                                y = bound.top - bound.height
                            } else if (bound.top > wh - bound.top) {
                                y = 0
                                this.height = bound.top
                            } else {
                                y = bound.top
                                this.height = wh - bound.top
                            }
                        } else {
                            y = bound.top - (bound.bottom - wh)
                            if (y < 0) {
                                y = 0
                                this.height = wh
                            }
                        }
                        this.position.y = y + 'px'
                    }
                })
            }
        },
        template: `
<div id="explorer-menu" @contextmenu.prevent class="menu" :style="style" v-if="state" tabindex="1">
    <div class="menu-action">
        <div class="menu-action-item hover" v-for="(item,index) in showMenus" @click="onClick(item,index)" tabindex="1">
            <slot :menu="item" :index="index">
                <div class="menu-action-item-label">{{item.label}}</div>
                <div class="keybinding"></div>
            </slot>
        </div>
    </div>
</div>
`
    }
})('ActionMenu')
